﻿/*
 * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
 *
 * This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
 *
 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
 */

#ifndef ZLMEDIAKIT_JT1078_H
#define ZLMEDIAKIT_JT1078_H

#include <cstdint>
#include <string>

namespace mediakit {

#define JT1078_FRAME_MAP(XX) \
    XX(I_FRAME, 0) \
    XX(P_FRAME, 1) \
    XX(B_FRAME, 2) \
    XX(AUDIO_FRAME, 3) \
    XX(RAW_FRAME, 4)

// 数据类型,0000:视频 I 帧; 0001:视频 P 帧; 0010:视频 B 帧; 0011:音频帧; 0100:透传数据
enum class JT1078FrameType : uint8_t {
#define XX(name, value) name = value,
        JT1078_FRAME_MAP(XX)
#undef XX
    };

#define JT1078_SLICE_MAP(XX) \
    XX(ATOMIC, 0) \
    XX(BEGIN, 1) \
    XX(END, 2) \
    XX(MIDDLE, 3)

enum class JT1078SliceType : uint8_t {
#define XX(name, value) name = value,
    JT1078_SLICE_MAP(XX)
#undef XX
};

class JT1078Payload {
public:
    union {
        struct {
            // 当前帧的相对时间，单 位毫秒(ms)。
            uint64_t stamp;
            // 该帧与上一个视频关键帧之间的时间间隔，单 位毫秒(ms)
            uint16_t last_key_frame_interval;
            // 该帧与上一帧视频之间的时间间隔，单位毫秒 (ms)
            uint16_t last_frame_interval;
            // 数据体长度，不含此字段
            uint16_t size;
            // 数据体，不超过950 byte
            uint8_t data[1];
        } video;

        struct {
            uint64_t stamp;
            uint16_t size;
            uint8_t data[1];
        } audio;

        struct {
            uint16_t size;
            uint8_t data[1];
        } raw;
    };

public:
    static size_t getMinSize(JT1078FrameType type);

    uint16_t size(JT1078FrameType type) const;
    const uint8_t *data(JT1078FrameType type) const;
    std::string dumpString(JT1078FrameType type) const;
    uint64_t getStampMS(JT1078FrameType type) const;
    uint16_t getLastFrameInterval(JT1078FrameType type) const;
    uint16_t getLastKeyFrameInterval(JT1078FrameType type) const;
};

// jt1078头固定为\x30\x31\x63\x64
static constexpr size_t kJT1078_MAGIC_SIZE = 4;

const char *getFrameTypeName(JT1078FrameType type);
const char *getSliceTypeName(JT1078SliceType type);

bool isJT1078(const char *data, size_t len);
const char* getJT1078Tail(const char *data, size_t len, bool check_prefix = true);

} // namespace mediakit
#endif // ZLMEDIAKIT_JT1078_H
